//
// Created by bjliuyong on 2021/7/17.
//

#ifndef JVM_CONSTANTPOOL_H
#define JVM_CONSTANTPOOL_H

#include "memory/allocation.h"
#include "utilities/constantTag.h"

class ConstantPool {
private:
    u2 length;
    u1* _tags;
    u8* _data;

public:
    ConstantPool(u2 length){
        this->length = length;
        _tags = new u1[length];
        _data = new u8[length];
    };

    void method_at_put(u2 which, u2 class_index, u2 name_and_type_index){
        _tags[which] = JVM_CONSTANT_Methodref;
        _data[which] = name_and_type_index << 16 | class_index;
    }

    void field_at_put(u2 which, u2 class_index, u2 name_and_type_index){
        _tags[which] = JVM_CONSTANT_Fieldref;
        _data[which] = name_and_type_index << 16 | class_index;
    }
    
    void int_at_put(u2 which, int i){
        _tags[which] = JVM_CONSTANT_Integer;
        _data[which] = i;
    }

    void string_index_at_put(u2 which,u2 string_index){
        _tags[which] = JVM_CONSTANT_String;
        _data[which] = string_index;
    }

    void klass_index_at_put(u2 which ,u2 name_index){
        _tags[which] = JVM_CONSTANT_Class;
        _data[which] = name_index;
    }

    void utf8_index_at_put(u2 which ,char* uft8_string){
        _tags[which] = JVM_CONSTANT_Utf8;
        _data[which] = reinterpret_cast<u8>(uft8_string);
    }

    char* utf8_at(int which){
        return reinterpret_cast<char*>(_data[which]);
    }

    void double_at_put(int which, u8 bytes) {
        _tags[which] =  JVM_CONSTANT_Double;
        _data[which] =  bytes;
    }

    void name_and_type_at_put(int which,int name_index, int signature_index){
        _tags[which] =  JVM_CONSTANT_NameAndType;
        _data[which] =  signature_index << 16 | name_index  ;
    }

};

#endif //JVM_CONSTANTPOOL_H
